package repository

import (
	"fitness/go-admin/internal/model"

	"gorm.io/gorm"
)

type RoleRepository interface {
	Create(role *model.Role) error
	GetByID(id uint) (*model.Role, error)
	GetByCode(code string) (*model.Role, error)
	List() ([]model.Role, error)
	GetRolePermissions(roleID uint) ([]model.Permission, error)
	AssignPermission(roleID, permissionID uint) error
	RemovePermission(roleID, permissionID uint) error
}

type roleRepository struct {
	db *gorm.DB
}

func NewRoleRepository(db *gorm.DB) RoleRepository {
	return &roleRepository{db: db}
}

func (r *roleRepository) Create(role *model.Role) error {
	return r.db.Create(role).Error
}

func (r *roleRepository) GetByID(id uint) (*model.Role, error) {
	var role model.Role
	err := r.db.First(&role, id).Error
	return &role, err
}

func (r *roleRepository) GetByCode(code string) (*model.Role, error) {
	var role model.Role
	err := r.db.Where("code = ?", code).First(&role).Error
	return &role, err
}

func (r *roleRepository) List() ([]model.Role, error) {
	var roles []model.Role
	err := r.db.Where("status = ?", 1).Order("id ASC").Find(&roles).Error
	return roles, err
}

func (r *roleRepository) GetRolePermissions(roleID uint) ([]model.Permission, error) {
	var permissions []model.Permission
	err := r.db.Table("permissions").
		Joins("INNER JOIN role_permissions ON permissions.id = role_permissions.permission_id").
		Where("role_permissions.role_id = ?", roleID).
		Find(&permissions).Error
	return permissions, err
}

func (r *roleRepository) AssignPermission(roleID, permissionID uint) error {
	rp := &model.RolePermission{
		RoleID:       roleID,
		PermissionID: permissionID,
	}
	return r.db.Create(rp).Error
}

func (r *roleRepository) RemovePermission(roleID, permissionID uint) error {
	return r.db.Where("role_id = ? AND permission_id = ?", roleID, permissionID).
		Delete(&model.RolePermission{}).Error
}
